#include "userhandler.h"
UserHandler::UserHandler(std::shared_ptr<ConnPool> &pro_ptr):pro_ptr(pro_ptr), BKSHandler("UserHandler")
{
    _DTS = DispatchTaskService::getInstance();
    _DTS->subscribe(EVENT_MOBILE_GET_CODE_REQ, this);
    _DTS->subscribe(EVENT_MOBILE_CODE_RSP, this);
    _DTS->subscribe(EVENT_LOGIN_REQ, this);
    _DTS->subscribe(EVENT_LOGIN_RSP, this);
}

UserHandler::~UserHandler()
{
    _DTS->unsubscribe(EVENT_MOBILE_GET_CODE_REQ, this);
    _DTS->unsubscribe(EVENT_MOBILE_CODE_RSP, this);
    _DTS->unsubscribe(EVENT_LOGIN_REQ, this);
    _DTS->unsubscribe(EVENT_LOGIN_RSP, this);
}

BKSEvent*UserHandler::handle(BKSEvent *ev)
{   
    if(!ev){
        LOG_ERROR("BKSEvent::handle_mobile_get_code_req ---> ev is null.\n");
        return NULL;
    }

    u32 eid = ev->get_eid();

    if(eid == EVENT_MOBILE_GET_CODE_REQ){
        return handle_mobile_get_code_req((MobileCodeReqEv*)ev);
    }
    else if(eid == EVENT_LOGIN_REQ){
        return handle_login_req((LoginReqEv*)ev);
    }
    else if(eid == EVENT_RECHARGE_REQ){
        //...
    }

    return NULL;
}

MobileCodeRspEv *UserHandler::handle_mobile_get_code_req(MobileCodeReqEv *ev)
{
    _mobile = ev->get_mobile();
    i32 icode = 0;
    
    icode = generateicode();

    //...

    _mobile_code_Map[_mobile] = icode;

    return new MobileCodeRspEv(200, icode);
}

i32 UserHandler::generateicode()
{
    i32 icode = 0; 

    srand((unsigned int)time(NULL));

    icode = (unsigned int)(rand() % (999999 - 100000) + 100000);

    return icode;
}

LoginRspEv *UserHandler::handle_login_req(LoginReqEv *ev){
    LoginRspEv *rspev = NULL;
    std::string _mobile = ev->get_mobile();
    i32 icode = ev->get_icode();
    {
        std::lock_guard<std::mutex> lk(m);
        auto iter = _mobile_code_Map.find(_mobile);
        if(iter == _mobile_code_Map.end() || (iter != _mobile_code_Map.end() && iter->second != icode)){
            rspev = new LoginRspEv(ERRORCODE_INVALID_DATA);
        }
    }
    if(rspev){
        return rspev;
    }
    auto conn = pro_ptr->getConn();
    char sql[256] = "\0";
    sprintf(sql, "SELECT COUNT(*) FROM userinfo WHERE mobile = '%s'", _mobile.c_str()); 
    bool isquery = false;
    {
        std::shared_lock<std::shared_mutex> lk(_m);
        isquery = conn->query(sql);
    }
    if(!isquery){
        memset(sql, 0, sizeof(sql));
        sprintf(sql, "INSERT INTO userinfo (mobile) VALUES('%s')", _mobile.c_str()); 
        bool res  = false; 
        {
            std::lock_guard<std::mutex> lk(m);
            res = conn->query(sql);
        }
        if(!res){
            rspev = new LoginRspEv(ERRORCODE_PROCESS_FAILED);
        } 
    }
    return new LoginRspEv(200);
}